package com.rockcent.mall.controller;

import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.RBeanUtils;
import com.rockcent.common.utils.RDateFormatUtils;
import com.rockcent.common.utils.RDateUtils;
import com.rockcent.mall.Routes;
import com.rockcent.mall.helper.UserHelper;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.*;
import com.rockcent.mall.lib.dto.MerchantOrderDto;
import com.rockcent.mall.lib.dto.MerchantOrderItemDto;
import com.rockcent.mall.lib.dto.UserInfoDto;
import com.rockcent.mall.lib.helper.OrderEventHelper;
import com.rockcent.mall.lib.repository.*;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by HK on 16/10/25.
 * 商家订单模块
 */
@RestController
public class MerchantOrderController extends BaseController {

    private final Logger log = LoggerFactory.getLogger(MerchantOrderController.class);

    @Autowired
    private UserHelper userHelper;

    @Autowired
    private MerchantOrderRepository merchantOrderRepository;

    @Autowired
    private MerchantOrderItemRepository merchantOrderItemRepository;

    @Autowired
    private MerchantOrderVerificationRepository merchantOrderVerificationRepository;

    @Autowired
    private MallLogisticsRepository mallLogisticsRepository;

    @Autowired
    private MerchantStoreRepository merchantStoreRepository;

    @Autowired
    private OrderEventHelper orderEventHelper;


    //根据平台订单号、商家ID查询商家订单
    @RequestMapping(value = "/merchant/order/qiutian_list", method = RequestMethod.GET)
    public JsonResult merchantOrderList(HttpServletRequest request, MerchantOrderDto dto) {
        RestDoing doing = jsonResult -> {
            List<MerchantOrder> merchantOrderList = merchantOrderRepository.findByMallOrderNum(dto.getMallOrderNum());
            jsonResult.data = merchantOrderList;
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/order/page 订单分页
     * @apiGroup MERCHANT_ORDER
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken <code>必要参数</code> 用户token
     * @apiHeader {String} domain <code>必要参数</code> 请求域名
     *
     * @apiParam  {String=ALL("全部订单"), WAIT_PAYING("待付款"), WAIT_SHIPPED("待发货"), WAIT_SHOP_PICKUP("待自提"), SHIPPED("已发货"), APPLY_REFUND("待退款"), WAIT_USE("待使用"), FINISHED("已完成"), FINISHED_REFUND("已退款")} status <code>必要参数</code> 默认ALL 订单状态
     * @apiParam {String} orderNum 订单号
     * @apiParam {String} customerName 买家名称
     * @apiParam {String} shoppingManPhone 收货人/手机
     * @apiParam {String=GOODS("商品订单"), SERVICE("服务订单")} orderType <code>必要参数</code> 默认ALL 订单类型
     * @apiParam {String=MARKET("分销订单")} sourceType 默认为空 订单类型
     * @apiParam {String=SHOP_PICKUP("门店自提"), SHIPPING("物流配送")} productShoppingType <code>必要参数</code> 默认ALL 配送方式
     * @apiParam {Date} beginDate 开始时间
     * @apiParam {Date} endDate 结束时间
     *
     * @apiSuccess {Long} id 订单ID
     * @apiSuccess {String} customerName 买家名称
     * @apiSuccess {String} shoppingMan 收货人
     * @apiSuccess {String} shoppingManPhone 收货人号码
     * @apiSuccess {String} address 收货人地址
     * @apiSuccess {BigDecimal} amount 订单金额
     * @apiSuccess {Date} dateCreated 下单时间
     * @apiSuccess {String} orderNum 订单号
     * @apiSuccess {String=WAIT_PAYING("待支付"), WAIT_STOCK("待备货"), CANCEL("取消"), PAYED("已支付"), WAIT_SHIPPED("等待发货"), SHIPPED("已发货"), WAIT_SHOP_PICKUP("到店自提"), PART_SHOP_PICKUP("部分到店自提"), CONFIRM_PICKUP("确认自提"), CONFIRM("已确认"), WAIT_USE("待使用"), PART_USE("部分使用"), USED("已使用"), FINISHED("已完成"), APPLY_REJECT("申请退货"), FINISHED_REJECT("已完成退货"), APPLY_REFUND("申请退款"), FINISHED_REFUND("已完成退款"} status 订单号
     * @apiSuccess {String} remark 订单备注
     * @apiSuccess {String=SHOP_PICKUP("到店自提"), SHIPPING("物流")} productShoppingType 配送类型
     * @apiSuccess {String=SELF("自营下单"), MARKET("分销下单")} sourceType 是否分销订单
     * @apiSuccess {String=GOODS("实物商品"), SERVICE("到店服务")} orderType 订单类型
     * @apiSuccess {Long} merchantOrderItemList_productId 产品编号
     * @apiSuccess {String} merchantOrderItemList_productName 产品名称
     * @apiSuccess {String} merchantOrderItemList_logoUrl 产品logo
     * @apiSuccess {String} logisticsCode 物流公司编码
     * @apiSuccess {String=SELF("默认"),SUPPLIER("供应商"), DISTRIBUTOR("分销商")} merchantRole 商家角色 当订单为分销订单时,用于区分供应商或者分销商
     * @apiSuccess {BigDecimal} merchantOrderItemList_singleAmount 产品单价
     * @apiSuccess {Boolean} merchantOrderItemList_productRefundable 是否支持过期退
     * @apiSuccess {Long} merchantOrderItemList_buyCount 数量
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功"
     * "data":{
     *      "id": 23,
     *      "customerName": "张三",
     *      "shoppingMan": "李四",
     *      "shoppingManPhone": "15023342245",
     *      "address": "海珠可住",
     *      "amount": "234.12",
     *      "dateCreated": "2016-08-11 16:27:32",
     *      "orderNum": "2343224",
     *      "status": "SHIPPED",
     *      "remark": "我要黄色,我要黄色,我要黄色",
     *      "productShoppingType": "SHIPPING",
     *      "sourceType": "SELF",
     *      "orderType": "SERVICE",
     *      "logisticsCode": "shentong",
     *      "merchantRole": "self",
     *      "merchantOrderItemList" :[{
     *          "productId" : 2342,
     *          "productName" : "黄色",
     *          "logoUrl" : "234234/asdfasdf.jpg",
     *          "singleAmount" : "34.2",
     *          "productRefundable" : false,
     *          "buyCount" : 3
     *      },
     *      ........
     *      ]
     *  },
     *  .....
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_ORDER_PAGE, method = RequestMethod.GET)
    public JsonResult merchantOrderPage(HttpServletRequest request, MerchantOrderDto dto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {


            if (StringUtils.isBlank(dto.getOrderType())){
                jsonResult.remind("订单类型 不能为空",log);
                return;
            }
            if (StringUtils.isBlank(dto.getStatus())){
                jsonResult.remind("订单状态 不能为空",log);
                return;
            }
            if (StringUtils.isBlank(dto.getProductShoppingType())){
                jsonResult.remind("配送方式 不能为空",log);
                return;
            }

            //默认查询时间为近一个月
            if (StringUtils.isBlank(dto.getBeginDate())) {
                dto.setBeginDate(RDateFormatUtils.formatParseDatePattern(RDateUtils.beforeDate(30)));
                dto.setEndDate(RDateFormatUtils.formatParseDatePattern(new Date()));
            }
            if (StringUtils.isNotBlank(dto.getStatus())&& !EnumUtils.isValidEnum(OrderStatus.class, dto.getStatus())){
                jsonResult.remind("订单类型只允许 ALL(\"全部订单\"), WAIT_PAYING(\"待付款\"), WAIT_SHIPPED(\"待发货\"), SHOP_PICKUP(\"待自提\"), SHIPPED(\"待发货\"), APPLY_REFUND(\"待退款\"), WAIT_USE(\"待使用\"), FINISHED(\"已完成\"), FINISHED_REFUND(\"已退款\")",log);
                return;
            }
            PageResult<MerchantOrderDto> pageResult = merchantOrderRepository.findMerchantOrderPage(userInfoDto.merchant.getId(), dto, this.getPage(dto.getPageNo(), dto.getPageSize()));
            pageResult.data.stream().map(merchantOrder -> {
                List<MerchantOrderItem> merchantOrderItemList = merchantOrderItemRepository.findByMerchantOrderId(merchantOrder.getId());
                merchantOrder.setMerchantOrderItemList(merchantOrderItemList);
                return merchantOrder;
            }).collect(Collectors.toList());
            pageResult.setUrl(Routes.MERCHANT_ORDER_PAGE);
            jsonResult.data = pageResult;
        };
        return doing.go(request, log);
    }

    /**
     * @api {put} /merchant/delivery/now 立即发货
     * @apiGroup MERCHANT_ORDER
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {Long} id 订单ID
     * @apiParam {Long} logisticsId 物流公司ID
     * @apiParam {String} logisticsNumber 快递单号
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *    "code": "1",
     *    "desc": "成功"
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_DELIVERY_NOW, method = RequestMethod.PUT)
    public JsonResult deliveryNow(HttpServletRequest request, @RequestBody MerchantOrderDto dto){
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (dto.getId() == null) {
                jsonResult.remind(MerchantOrder.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }

            if (dto.getLogisticsId() == null) {
                jsonResult.remind(MerchantOrder.CHECK_LOGISTICS_ID_IS_NOT_NULL,log);
                return;
            }

            if (StringUtils.isBlank(dto.getLogisticsNumber())) {
                jsonResult.remind(MerchantOrder.CHECK_LOGISTICS_NUMBER_IS_NOT_NULL,log);
                return;
            }

            MerchantOrder merchantOrder = merchantOrderRepository.findByLogisticsNumberAndLogisticsId(dto.getLogisticsNumber(), dto.getLogisticsId());
            if (merchantOrder != null) {
                jsonResult.remind("快递单号不能重复使用",log);
                return;
            }

            merchantOrder = merchantOrderRepository.findByIdAndMerchantId(dto.getId(), userInfoDto.merchant.getId());
            if (merchantOrder == null) {
                jsonResult.remind(MerchantOrder.REMIND_RECORD_IS_NOT_EXIST,log);;
                return;
            }

            if (OrderStatus.WAIT_SHIPPED == merchantOrder.getStatus() || OrderStatus.SHIPPED == merchantOrder.getStatus()) {
                MallLogistics mallLogistics = mallLogisticsRepository.findOne(dto.getLogisticsId());
                if (mallLogistics == null) {
                    jsonResult.remind("物流公司不存在",log);
                    return;
                }
                merchantOrder.setLogisticsId(mallLogistics.getId());
                merchantOrder.setLogisticsName(mallLogistics.getName());
                merchantOrder.setLogisticsNumber(dto.getLogisticsNumber());
                merchantOrder.setDateDelivered(new Date());
                merchantOrder.setDateReceived(DateUtils.addDays(new Date(), 15));//默认十天为收货时间
                merchantOrder.setStatus(OrderStatus.SHIPPED);
                merchantOrder.setLogisticsCode(mallLogistics.getLogisticsCode());
                merchantOrderRepository.save(merchantOrder);

                if (merchantOrder.getMarketOrderNum() != null) {
                    MerchantOrder marketOrder = merchantOrderRepository.findByMarketOrderNumAndMerchantRole(merchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR);
                    marketOrder.setLogisticsId(mallLogistics.getId());
                    marketOrder.setLogisticsName(mallLogistics.getName());
                    marketOrder.setLogisticsNumber(dto.getLogisticsNumber());
                    marketOrder.setDateDelivered(new Date());
                    marketOrder.setDateReceived(DateUtils.addDays(new Date(), 15));//默认十五天为收货时间
                    marketOrder.setLogisticsCode(mallLogistics.getLogisticsCode());
                    marketOrder.setStatus(OrderStatus.SHIPPED);
                    merchantOrderRepository.save(marketOrder);
                }
                orderEventHelper.saveOrderEvent(merchantOrder, OrderEventType.SHIPPED, userInfoDto.merchant.getName(), userInfoDto.merchant.getId());
            }else{
                jsonResult.remind(MerchantOrder.MERCHANT_ORDER_WAIT_SHIPPED,log);
                return;
            }

        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/order/logistics/info 物流详情
     * @apiGroup MERCHANT_ORDER
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {Long} id <code>必传参数</code> 订单ID
     *
     * @apiSuccess {Date} dateDelivered 发货时间
     * @apiSuccess {Date} dateReceived 收货时间
     * @apiSuccess {String} logisticsName 快递公司名称
     * @apiSuccess {String=SHIPPED("自动确认收货"), FINISHED("收货时间")} status 快递公司名称
     * @apiSuccess {String} logisticsNumber 快递单号
     * @apiSuccess {String} orderNum 订单号
     * @apiSuccess {String} merchantStoreName 门店名称
     * @apiSuccess {String} merchantStoreMobile 名店电话号码
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功"
     * "data":{
     *      "id": 23,
     *      "dateDelivered": "2016-08-11 16:27:32",
     *      "dateReceived": "2016-08-11 16:27:32",
     *      "logisticsName": "顺丰",
     *      "status": "SHIPPED",
     *      "logisticsNumber": "234234234",
     *      "merchantStoreName": "珠江新出",
     *      "merchantStoreMobile": "13567834567",
     *      "orderNum": "2343224"
     *  }
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_ORDER_LOGISTICS_INFO, method = RequestMethod.GET)
    public JsonResult logisticsInfo(HttpServletRequest request, MerchantOrderDto dto){
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (dto.getId() == null) {
                jsonResult.remind(MerchantOrder.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }
            MerchantOrder merchantOrder = merchantOrderRepository.findByIdAndMerchantId(dto.getId(), userInfoDto.merchant.getId());
            if (merchantOrder == null) {
                jsonResult.remind(MerchantOrder.REMIND_RECORD_IS_NOT_EXIST,log);;
                return;
            }
            RBeanUtils.copyProperties(merchantOrder, dto);
            dto.setStatus(merchantOrder.getStatus().toString());
            if (merchantOrder.getMerchantStoreId() != null) {
                MerchantStore merchantStore = merchantStoreRepository.findByIdAndMerchantIdAndMallIdAndIsDelete(merchantOrder.getMerchantStoreId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId(), Whether.NO);
                if (merchantStore != null) {
                    dto.setMerchantStoreMobile(merchantStore.getPhone());
                    dto.setMerchantStoreName(merchantStore.getName());
                }
            }
            jsonResult.data = dto;
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/overtime/order/record 过期订单
     * @apiGroup MERCHANT_ORDER
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {Long} id <code>必传参数</code> 订单ID
     *
     * @apiSuccess {Date} productDateDisabled 退货日期
     * @apiSuccess {boolean} productRefundableIsRun 是否支持过期退
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功"
     * "data":[
     *      {
     *          "productDateDisabled": "2016-08-11 16:27:32"
     *          "productRefundableIsRun": "true"
     *      }
     *     .....
     *  ]
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_OVERTIME_ORDER_RECORD, method = RequestMethod.GET)
    public JsonResult overtimeOrderInfo(HttpServletRequest request, MerchantOrderDto dto){
        RestDoing doing = jsonResult -> {
            if (dto.getId() == null) {
                jsonResult.remind(MerchantOrder.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }
            List<MerchantOrderItem> merchantOrderItemList = merchantOrderItemRepository.findByMerchantOrderId(dto.getId());
            jsonResult.data = merchantOrderItemList;
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/order/verification/record 核销记录
     * @apiGroup MERCHANT_ORDER
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String} orderNum <code>必传参数</code> 商家订单号
     *
     * @apiSuccess {Date} dateCreated 核销时间
     * @apiSuccess {String} verifyCount 核销数量
     * @apiSuccess {String} verificationWay 核销方式
     * @apiSuccess {String} merchantStoreName 核销门店
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功"
     * "data":[
     *      {
     *          "dateCreated": "2016-08-11 16:27:32",
     *          "verifyCount": 2,
     *          "verificationWay": "SCAN",
     *          "merchantStoreName": "珠江"
     *      }
     *     ...
     *  ]
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_ORDER_VERIFICATION_RECORD, method = RequestMethod.GET)
    public JsonResult orderVerificationRecord(HttpServletRequest request, MerchantOrderDto dto){
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (StringUtils.isBlank(dto.getOrderNum())) {
                jsonResult.remind("商家订单号 不能为空",log);
                return;
            }
            MerchantOrder merchantOrder = merchantOrderRepository.findByOrderNumAndMerchantIdAndMallId(dto.getOrderNum(), userInfoDto.merchant.getId(), userInfoDto.mall.getId());
            if (MerchantOrderMerchantRole.DISTRIBUTOR == merchantOrder.getMerchantRole()) {
                merchantOrder = merchantOrderRepository.findByMarketOrderNumAndMerchantRole(merchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.SUPPLIER);
                dto.setOrderNum(merchantOrder.getOrderNum());
            }
            List<MerchantOrderVerification> orderVerificationList = merchantOrderVerificationRepository.findByMerchantOrderNumAndMerchantIdAndMallId(dto.getOrderNum(), merchantOrder.getMerchantId(), merchantOrder.getMallId());
            jsonResult.data = orderVerificationList;
        };
        return doing.go(request, log);
    }

    /**
     * @api {put} /merchant/order/confirm/stock 补充备货
     * @apiGroup MERCHANT_ORDER
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {Long} id 订单ID
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *    "code": "1",
     *    "desc": "成功"
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_ORDER_CONFIRM_STOCK, method = RequestMethod.PUT)
    public JsonResult orderConfirmStock(HttpServletRequest request, @RequestBody MerchantOrderDto dto){
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (dto.getId() == null) {
                jsonResult.remind(MerchantOrder.CHECK_ID_IS_NOT_NULL,log);;
                return;
            }
            MerchantOrder merchantOrder = merchantOrderRepository.findByIdAndMerchantId(dto.getId(), userInfoDto.merchant.getId());
            if (merchantOrder == null) {
                jsonResult.remind(MerchantOrder.REMIND_RECORD_IS_NOT_EXIST,log);;
                return;
            }
            if (MerchantOrderMerchantRole.DISTRIBUTOR == merchantOrder.getMerchantRole()) {
                jsonResult.remind("操作有误,请联系开发人员",log);
                return;
            }
            if (OrderStatus.WAIT_STOCK != merchantOrder.getStatus()) {
                jsonResult.remind("订单不处于备货状态",log);
                return;
            }
            if (merchantOrder.getMarketOrderNum() != null) {
                MerchantOrder marketOrder = merchantOrderRepository.findByMarketOrderNumAndMerchantRole(merchantOrder.getMarketOrderNum(), MerchantOrderMerchantRole.DISTRIBUTOR);
                marketOrder.setDateStock(new Date());
                marketOrder.setStatus(OrderStatus.WAIT_SHOP_PICKUP);
                merchantOrderRepository.save(merchantOrder);
            }
            merchantOrder.setDateStock(new Date());
            merchantOrder.setStatus(OrderStatus.WAIT_SHOP_PICKUP);
            merchantOrderRepository.save(merchantOrder);
        };
        return doing.go(request, log);
    }

}
